
export function preferred(navigator) {
    return navigator.languages || [navigator.language || navigator.userLanguage || "en"];
}

/**
 * Parses an IETF language tag into pieces.
 *
 * {language: "zh", script: "Hans", region: "CN"}
 * {language: "en", script: "", region: "US"}
 * {language: "en", script: "", region: ""}
 * {language: "", script: "", region: ""}
 *
 * @param {string} tag
 */
export function parse(tag) {
    const result = {language: "", script: "", region: ""};
    const parts = (tag || "").toLowerCase().split("-");
    for (let i = 0; i < parts.length; i++) {
        const part = parts[i];
        if (part.length === 1) {  // stop parsing when we hit an extension
            break;
        }
        if (i === 0) {
            result.language = part;
        } else if (/^[a-z]{4}$/.test(part)) {
            result.script = part.substring(0, 1).toUpperCase() + part.substring(1);
        } else if (/^([a-z]{2}|\d{3})$/.test(part)) {
            result.region = part.toUpperCase();
        }
    }
    return result;
}

/**
 * Returns the most appropriate match for the specified language tag, or "" if none can be found.
 *
 * @param struct a parsed IETF language tag
 * @returns {string}
 */
export function match(struct) {
    // $LANG$
    switch (struct.language) {
        case "en": return "en";
        case "cs": return "cs";
        case "fr": return "fr";
        case "ja": return "ja";
        case "ko": return "ko";
        case "pt": return "pt";
        case "ru": return "ru";
        case "zh":
            switch (struct.script) {
                // https://github.com/mozilla/addons-server/issues/5829
                // https://unicode-org.github.io/cldr-staging/charts/37/supplemental/likely_subtags.html
                // https://www.drupal.org/project/wysiwyg/issues/923304
                // https://www.w3.org/International/articles/language-tags/index.en
                case "Hant": return "zh-TW";  // should probably be zh-Hant
                case "Hans": return "zh-CN";  // should probably be zh-Hans
            }
            switch (struct.region) {
                case "HK":
                case "MO":
                case "TW": return "zh-TW";  // should probably be zh-Hant
                case "SG":
                case "CN": return "zh-CN";  // should probably be zh-Hans
            }
    }
    return "";
}

export function mostPreferredLang(navigator) {
    const preference = preferred(navigator);
    for (let i = 0; i < preference.length; i++) {
        const parsed = parse(preference[i]);
        const matched = match(parsed);
        if (matched) return matched;
    }
    return "";
}
